import mx.xpath.XPathAPI;

import org.molamil.acto.commands.CommandContext;
import org.molamil.acto.commands.cmd.CmdInit;
import org.molamil.acto.core.Logger;
import org.molamil.acto.core.ParserError;
import org.molamil.acto.props.PropsParser;
import org.molamil.commons.StringUtil;
import org.molamil.acto.params.ParamsParser;

/**
 * @author Jorge Hernandez
 */
class org.molamil.acto.commands.CommandsParser {
	
	
	// Constants
	
	public static var ERROR_INVALID_ROOT:String = "ERROR: Invalid node: <commands> expected, <{node}> found.";
	
	
	// Properties
	
	private static var log:Logger = Logger.getLogger("CommandsParser");
	
	
	// Functions
	
	public static function parse(xml:XML):Array {
		
		log.info("parse()");
		
		CmdInit.init();
		
		if (xml.firstChild.nodeName != "commands") {
			log.severe("ParserError");
			var msg:String = StringUtil.replace(ERROR_INVALID_ROOT, "{node}", xml.firstChild.nodeName);
			throw new ParserError(msg);
		}
		
		// Create the array.
		var a:Array = new Array();
		
		// Get pages.
		var commandNodes:Array = XPathAPI.selectNodeList(xml.firstChild, "/commands/command");
		log.debug(commandNodes.length + " commands found");
		
		// Iterate the pages.
		for (var i:Number = 0;i < commandNodes.length; i++) {
			
			log.debug("processing command node " + i);
			
			var commandNode:XMLNode = commandNodes[i];
			var context:CommandContext = parseContext(commandNode);
				
			a.push(context);
			
		}

		return a;
		
	}
	
	private static function parseContext(node:XMLNode):CommandContext {
		
		var context:CommandContext = new CommandContext();
	
		context.name = node.attributes["name"];
		log.debug("name = " + context.name);
		
		context.title = node.attributes["title"];
		log.debug("title = " + context.title);
		
		context.target = node.attributes["target"];
		log.debug("target = " + context.target);
		
		context.className = node.attributes["class"];
		log.debug("className = " + context.className);
		
		//TODO: Implement command chaining.
		
		var depends:String = StringUtil.replace(node.attributes["depends"], " ", "");
		context.depends = depends != "" ? depends.split(",") : null;
		log.debug("depends = " + context.depends);
		
		var role:String = node.attributes["role"];
		context.role = role != "" ? role : null;
		log.debug("role = " + context.role);
		
		context.paramsMode = node.attributes["params"].toLowerCase();
		log.debug("paramsMode = " + context.paramsMode);
		
		context.cache = node.attributes["cache"].toLowerCase();
		log.debug("cache = " + context.cache);
		
		context.props = PropsParser.parse(new XML(node.toString()));
		
		context.params = ParamsParser.parse(new XML(node.toString()));
		
		return context;
			
	}
	
	
}
